package com.example.portablefortheelderlybackground.sevice.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.portablefortheelderlybackground.common.StringCommon;
import com.example.portablefortheelderlybackground.common.key.paramsKey;
import com.example.portablefortheelderlybackground.common.redis.redisKey;
import com.example.portablefortheelderlybackground.mapper.dishMapper;
import com.example.portablefortheelderlybackground.pojo.dish.dish;
import com.example.portablefortheelderlybackground.sevice.dishService;
import com.example.portablefortheelderlybackground.utils.Response;
import com.example.portablefortheelderlybackground.vo.dishVo.dishVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.example.portablefortheelderlybackground.Enum.Message.ReturnMessageEnum.*;

@Service
@Slf4j
@Transactional(timeout = 3)
public class dishServiceImpl extends ServiceImpl<dishMapper, dish> implements dishService {

    private final
    RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public dishServiceImpl(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Response<Page<dish>> getDishList(Integer pages, Integer pageSize, String type) {
        //判读redis是否存在缓存
        Page<dish> dishPage = (Page<dish>) redisTemplate.opsForValue().get(redisKey.dishQueryKey + type);
        if (!ObjectUtils.isEmpty(dishPage)) {
            return Response.success(dishPage, SUCCESS.getCode(), SUCCESS.getMessage());
        }
        //查询所有的dish膳食,根据pages,和pageSize查询
        Page<dish> page = new Page<>(pages, pageSize);
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(dish::getType, type);
        //按照创建的时间进行排序
        queryWrapper.orderByAsc(dish::getCreateTime);
        baseMapper.selectPage(page, queryWrapper);
        //查询成功，将数据放到redis缓存中去
        redisTemplate.opsForValue().set(redisKey.dishQueryKey + type, page, StringCommon.TimeOut, TimeUnit.HOURS);
        //如果list为空,则返回系统繁忙
        return page.getRecords() == null ? Response.error(null, SERVER_ERROR.getCode(), SERVER_ERROR.getMessage()) : Response.success(page, SUCCESS.getCode(), SUCCESS.getMessage());
    }

    @Override
    public Response<dishVo> getDishById(String id) {
        dish singletonDish = (dish) redisTemplate.opsForValue().get(redisKey.dishKey + id);
        dishVo dishVo = new dishVo();
        if (!ObjectUtils.isEmpty(singletonDish)) {
            BeanUtils.copyProperties(singletonDish, dishVo);
            return Response.success(dishVo, SUCCESS.getCode(), SUCCESS.getMessage());
        }
        dish dishById = baseMapper.selectById(id);
        if (ObjectUtils.isEmpty(dishById)) {
            return Response.error(null, NULL_POINTER.getCode(), NULL_POINTER.getMessage());
        }
        //查到存进缓存
        redisTemplate.opsForValue().set(redisKey.dishKey + id, dishById, StringCommon.TimeOut, TimeUnit.HOURS);
        // 属性拷贝
        BeanUtils.copyProperties(dishById, dishVo);
        return Response.success(dishVo, SUCCESS.getCode(), SUCCESS.getMessage());
    }

    @Override
    public Response<dishVo> updateDishById(dish updateDish) {
        dishVo dishVo = new dishVo();
        LambdaQueryWrapper<dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(updateDish.getId() != null, dish::getId, updateDish.getId());
        //查询对应的实体类信息
        int updateFlag = baseMapper.update(updateDish, queryWrapper);
        if (updateFlag > 0) {
            log.error("{},id为{}的dish修改失败!", LocalDateTime.now(), updateDish.getId());
            return Response.error(null, SERVER_ERROR.getCode(), SERVER_ERROR.getMessage());
        }
        //修改成功时，请求redis相对应的缓存
        //清除dish:list缓存
        redisTemplate.opsForValue().getOperations().delete(redisKey.dishQueryKey + updateDish.getType());
        //清除对应dish:singleton:id
        redisTemplate.opsForValue().getOperations().delete(redisKey.dishKey + updateDish.getId());
        log.info("id为{}的dish数据修改成功!time:{}", updateDish.getId(), LocalDateTime.now());
        //返回对应的数据
        //拷贝属性
        BeanUtils.copyProperties(updateDish, dishVo);
        return Response.success(dishVo, UPDATE_SUCCESS.getCode(), UPDATE_SUCCESS.getMessage());
    }

    @Override
    public Response<dishVo> saveDish(dish saveDish) {
        dishVo dishVo = new dishVo();
        if (ObjectUtils.isEmpty(saveDish)) {
            log.error("dish数据为空,无法保存!-{}", LocalDateTime.now());
            return Response.error(null, NULL_POINTER.getCode(), NULL_POINTER.getMessage());
        }
        int save = baseMapper.insert(saveDish);
        if (save > paramsKey.NUM_ZERO) {
            log.info("{},成功保存一条dish数据,id为:{}", LocalDateTime.now(), saveDish.getId());
            //清除redis缓存
            //清除dishQueryKey:list
            redisTemplate.opsForValue().getOperations().delete(redisKey.dishQueryKey + saveDish.getType());
            BeanUtils.copyProperties(saveDish, dishVo);
            return Response.success(dishVo, SAVE_SUCCESS.getCode(), SAVE_SUCCESS.getMessage());
        }
        log.warn("数据不为空，但数据保存失败-{}", LocalDateTime.now());
        return Response.error(null, SAVE_ERROR.getCode(), SAVE_ERROR.getMessage());
    }

    @Override
    public Response<dishVo> saveDishBatch(List<dish> saveDishBatch) {
        return null;
    }

    @Override
    public Response<Boolean> deleteDish(String id) {
        //查询对应的实体类信息
        dish deleteDish = baseMapper.selectById(id);
        int removeFlag = baseMapper.deleteById(id);
        //
        if (removeFlag > paramsKey.NUM_ZERO) {
            //清除相对应的redis缓存,并清楚dishUser表相关连的数据
            redisTemplate.opsForValue().getOperations().delete(redisKey.dishQueryKey + deleteDish.getType());
            redisTemplate.opsForValue().getOperations().delete(redisKey.dishKey + id);
            log.info("删除成功!-{}", LocalDateTime.now());
            return Response.success(true, DELETE_SUCCESS.getCode(), DELETE_SUCCESS.getMessage());
        }
        log.info("删除失败!-{}", LocalDateTime.now());
        return Response.error(false, DELETE_ERROR.getCode(), DELETE_ERROR.getMessage());
    }
}
